package com.ruoyi.ncpsy.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.ncpsy.domain.NcpsyCropFertilizer;
import com.ruoyi.ncpsy.mapper.NcpsyAreaProductMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.abi.ABICodecException;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.config.Config;
import org.fisco.bcos.sdk.config.ConfigOption;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.crypto.keypair.ECDSAKeyPair;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.fisco.bcos.sdk.transaction.model.exception.TransactionBaseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.ncpsy.mapper.NcpsyAreaMapper;
import com.ruoyi.ncpsy.domain.NcpsyArea;
import com.ruoyi.ncpsy.service.INcpsyAreaService;

/**
 * 种植地信管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-08-09
 */
@Service
public class NcpsyAreaServiceImpl implements INcpsyAreaService 
{
    @Autowired
    private NcpsyAreaMapper ncpsyAreaMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private NcpsyAreaProductMapper ncpsyAreaProductMapper;
    /**
     * 查询种植地信管理
     * 
     * @param areaId 种植地信管理主键
     * @return 种植地信管理
     */
    @Override
    public NcpsyArea selectNcpsyAreaByAreaId(Long areaId)
    {
        return ncpsyAreaMapper.selectNcpsyAreaByAreaId(areaId);
    }

    /**
     * 查询种植地信管理列表
     * 
     * @param ncpsyArea 种植地信管理
     * @return 种植地信管理
     */
    @Override
    public List<NcpsyArea> selectNcpsyAreaList(NcpsyArea ncpsyArea)
    {
        return ncpsyAreaMapper.selectNcpsyAreaList(ncpsyArea);
    }

    /**
     * 新增种植地信管理
     * 
     * @param ncpsyArea 种植地信管理
     * @return 结果
     */
    @Override
    public int insertNcpsyArea(NcpsyArea ncpsyArea) throws Exception {
        ncpsyArea.setCreateTime(DateUtils.getNowDate());
        
        // 创建临时目录
        Path tempDir = null;
        try {
            tempDir = Files.createTempDirectory("bcos_sdk_");
            System.out.println("Created temporary directory: " + tempDir.toAbsolutePath());
            
            // 创建临时配置文件
            File tempConfigFile = new File(tempDir.toFile(), "config-example.toml");
            copyResourceToFile("BOOT-INF/classes/config-example.toml", tempConfigFile);
            
            // 创建临时证书目录
            File tempCertDir = new File(tempDir.toFile(), "conf");
            tempCertDir.mkdirs();
            
            // 复制证书文件
            File caCertFile = new File(tempCertDir, "ca.crt");
            copyResourceToFile("BOOT-INF/classes/conf/ca.crt", caCertFile);
            
            File sdkCertFile = new File(tempCertDir, "sdk.crt");
            copyResourceToFile("BOOT-INF/classes/conf/sdk.crt", sdkCertFile);
            
            File sdkKeyFile = new File(tempCertDir, "sdk.key");
            copyResourceToFile("BOOT-INF/classes/conf/sdk.key", sdkKeyFile);
            
            // 创建临时ABI目录
            File tempAbiDir = new File(tempDir.toFile(), "abi");
            tempAbiDir.mkdirs();
            System.out.println("Created temporary ABI directory: " + tempAbiDir.getAbsolutePath());
            
            // 复制ABI文件
            File ncpsyAreaAbiFile = new File(tempAbiDir, "NcpsyArea.abi");
            copyResourceToFile("BOOT-INF/classes/abi/NcpsyArea.abi", ncpsyAreaAbiFile);
            
            // 修改配置文件中的证书路径
            String configContent = new String(Files.readAllBytes(tempConfigFile.toPath()));
            configContent = configContent.replace("conf/ca.crt", tempCertDir.getAbsolutePath() + "/ca.crt");
            configContent = configContent.replace("conf/sdk.crt", tempCertDir.getAbsolutePath() + "/sdk.crt");
            configContent = configContent.replace("conf/sdk.key", tempCertDir.getAbsolutePath() + "/sdk.key");
            Files.write(tempConfigFile.toPath(), configContent.getBytes());
            
            // 初始化BcosSDK对象
            BcosSDK sdk = BcosSDK.build(tempConfigFile.getAbsolutePath());
            
            // 获取Client对象，此处传入的群组ID为1
            ncpsyAreaMapper.insertNcpsyArea(ncpsyArea);
            Client client = sdk.getClient(Integer.valueOf(1));
            String hash = sysUserMapper.selecthashById(ncpsyArea.getUserId());
            ECDSAKeyPair ecdsaKeyPair = new ECDSAKeyPair();
            CryptoKeyPair keyPair = ecdsaKeyPair.createKeyPair(hash);
            System.out.println("Using ABI path for TransactionProcessor: " + tempAbiDir.getAbsolutePath());
            AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, keyPair, tempAbiDir.getAbsolutePath(), "");
            
            // 创建调用交易函数的参数，此处为传入一个参数
            List<Object> params = new ArrayList<>();
            String area_id = ncpsyArea.getAreaId().toString();
            String user_id = ncpsyArea.getUserId().toString();
            String area_address = ncpsyArea.getAreaAddress().toString();
            String create_time = ncpsyArea.getCreateTime().toString();
            params.add(area_id);
            params.add(user_id);
            params.add(area_address);
            params.add(create_time);
            TransactionResponse transactionResponse = transactionProcessor.sendTransactionAndGetResponseByContractLoader("NcpsyArea", "0x95549a37967c196cd9ce91da5248a45043fd41fa", "insert", params);
            
            //获取交易哈希
            String transactionHash = transactionResponse.getTransactionReceipt().getTransactionHash();
            NcpsyArea ncpsyArea1 = new NcpsyArea();
            ncpsyArea1.setHash(transactionHash);
            ncpsyArea1.setAreaId(ncpsyArea.getAreaId());
            ncpsyAreaMapper.updateNcpsyArea(ncpsyArea1);
            
            return 1;
        } finally {
            // 清理临时目录
            if (tempDir != null) {
                deleteRecursively(tempDir.toFile());
            }
        }
    }

    /**
     * 修改种植地信管理
     * 
     * @param ncpsyArea 种植地信管理
     * @return 结果
     */
    @Override
    public int updateNcpsyArea(NcpsyArea ncpsyArea)
    {
        ncpsyArea.setUpdateTime(DateUtils.getNowDate());
        return ncpsyAreaMapper.updateNcpsyArea(ncpsyArea);
    }

    /**
     * 批量删除种植地信管理
     * 
     * @param areaIds 需要删除的种植地信管理主键
     * @return 结果
     */
    @Override
    public int deleteNcpsyAreaByAreaIds(Long[] areaIds) throws Exception {
        for (int i = 0; i < areaIds[i]; i++) {
            int cnt = ncpsyAreaProductMapper.selectAllByAreaIdByAreaId(areaIds[i]);
            if (cnt > 0){
                throw new Exception("该种植地下存在农产品，不能删除");
            }
        }
        return ncpsyAreaMapper.deleteNcpsyAreaByAreaIds(areaIds);
    }

    /**
     * 删除种植地信管理信息
     * 
     * @param areaId 种植地信管理主键
     * @return 结果
     */
    @Override
    public int deleteNcpsyAreaByAreaId(Long areaId)
    {
        return ncpsyAreaMapper.deleteNcpsyAreaByAreaId(areaId);
    }


    /**
     * 查询种植地信管理数量
     *
     * @return 数量
     */
     @Override
    public int selectNcpsyAreaCount(Long userId) {
        return ncpsyAreaMapper.selectNcpsyAreaCount(userId);
    }
    
    /**
     * 将类路径下的资源文件复制到临时文件
     * 
     * @param resourcePath 资源路径
     * @param targetFile 目标文件
     * @throws IOException IO异常
     */
    private void copyResourceToFile(String resourcePath, File targetFile) throws IOException {
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourcePath);
             OutputStream outputStream = new FileOutputStream(targetFile)) {
            
            if (inputStream == null) {
                throw new IOException("Resource not found: " + resourcePath);
            }
            
            // 添加日志输出，以便调试
            System.out.println("Copying resource: " + resourcePath + " to " + targetFile.getAbsolutePath());
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            
            // 确认文件复制成功
            System.out.println("Successfully copied resource: " + resourcePath);
        }
    }
    
    /**
     * 递归删除文件或目录
     * 
     * @param file 要删除的文件或目录
     */
    private void deleteRecursively(File file) {
        if (file == null) {
            return;
        }
        
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                for (File child : children) {
                    deleteRecursively(child);
                }
            }
        }
        
        file.delete();
    }
}
